package com.baoyouqun.controller.union;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baoyouqun.entity.FileInfoLocal;
import com.baoyouqun.service.IFileStorageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 文件存储控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/files")
@RequiredArgsConstructor
@Tag(name = "文件存储接口", description = "提供文件上传、下载、删除和查询功能")
public class FileStorageController {

    private final IFileStorageService fileStorageService;

    @PostMapping("/upload")
    @Operation(summary = "上传文件")
    public ResponseEntity<FileInfoLocal> uploadFile(@RequestBody
                                                    @Parameter(description = "上传的文件") @RequestParam("file") MultipartFile file,
                                                    @Parameter(description = "存储桶名称") @RequestParam("bucket") String bucket,
                                                    @Parameter(description = "上传者ID") @RequestParam(value = "uploaderId", required = false) Long uploaderId) {
        try {
            FileInfoLocal fileInfo = fileStorageService.upload(file, bucket, uploaderId);
            return ResponseEntity.ok(fileInfo);
        } catch (Exception e) {
            log.error("文件上传失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    @GetMapping("/download/{fileId}")
    @Operation(summary = "下载文件")
    public ResponseEntity<Void> downloadFile(  // 改为返回Void，通过流直接写入响应
                                               @Parameter(description = "文件ID") @PathVariable Long fileId,
                                               HttpServletResponse response) {  // 新增response参数
        try {
            // 获取文件信息
            FileInfoLocal fileInfo = fileStorageService.getFileInfoLocal(fileId);
            if (fileInfo == null) {
                return ResponseEntity.notFound().build();
            }

            // 设置响应头
            response.setContentType(fileInfo.getFileType());
            String encodedFileName = URLEncoder.encode(fileInfo.getOriginalFileName(), StandardCharsets.UTF_8);
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");
            response.setContentLengthLong(fileInfo.getFileSize());  // 设置文件大小

            // 流式传输（修复OOM）
            try (InputStream is = fileStorageService.download(fileId);
                 OutputStream os = response.getOutputStream()) {
                byte[] buffer = new byte[8192];
                int len;
                while ((len = is.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
            }
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            log.error("文件下载失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    // 其他方法保持不变...
    @DeleteMapping("/{fileId}")
    @Operation(summary = "删除文件")
    public ResponseEntity<Boolean> deleteFile(
            @Parameter(description = "文件ID") @PathVariable Long fileId) {
        try {
            boolean result = fileStorageService.delete(fileId);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("文件删除失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(false);
        }
    }

    @GetMapping("/{fileId}")
    @Operation(summary = "获取文件信息")
    public ResponseEntity<FileInfoLocal> getFileInfoLocal(
            @Parameter(description = "文件ID") @PathVariable Long fileId) {
        try {
            FileInfoLocal fileInfo = fileStorageService.getFileInfoLocal(fileId);
            if (fileInfo == null) {
                return ResponseEntity.notFound().build();
            }
            return ResponseEntity.ok(fileInfo);
        } catch (Exception e) {
            log.error("获取文件信息失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

    @GetMapping("/list")
    @Operation(summary = "分页查询文件列表")
    public ResponseEntity<IPage<FileInfoLocal>> queryFiles(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") int pageNum,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") int pageSize,
            @Parameter(description = "存储桶名称") @RequestParam(required = false) String bucket,
            @Parameter(description = "文件名（模糊查询）") @RequestParam(required = false) String fileName,
            @Parameter(description = "文件类型") @RequestParam(required = false) String fileType) {
        try {
            IPage<FileInfoLocal> filePage = fileStorageService.queryFiles(pageNum, pageSize, bucket, fileName, fileType);
            return ResponseEntity.ok(filePage);
        } catch (Exception e) {
            log.error("查询文件列表失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }
}